package com.tentact.coolmeetingtest.util;

import com.tentact.coolmeetingtest.support.VoAutoBuilder;

import java.sql.*;
import java.util.Arrays;
import java.util.List;

/**
 * @author 星环
 * @date 2022/12/29 16:20:05
 * @description
 */
public class JDBCUtil {
    public static final String driver = "com.mysql.cj.jdbc.Driver";
    public static final String url = "jdbc:mysql://localhost:3306/cool_meeting?serverTimezone=UTC";
    public static final String user = "root";
    public static final String pwd ="zx123123";

    private static Connection conn = null;

    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(url, user, pwd);
        } catch (SQLException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public static Connection getConn(){
        try {
            if(conn == null || conn.isClosed()){
                conn = DriverManager.getConnection(url,user,pwd);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return conn;
    }

    public static PreparedStatement getPreparedStatementWithGeneratedKeys(String sql, Object... args){
        try {
            PreparedStatement statement = getConn().prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            setArgs(statement,args);
            return statement;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }


    public static PreparedStatement getPreparedStatement(String sql, Object... args){
        try {
            PreparedStatement statement = getConn().prepareStatement(sql);
            setArgs(statement,args);
            return statement;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public static void setArgs(PreparedStatement ps,Object... args){
        try {
            for (int i = 0;i < args.length;i++) {
                if(args[i] instanceof String str){
                    ps.setString(i+1,str);
                }else if(args[i] instanceof  Integer integer){
                    ps.setInt(i+1,integer);
                }else if(args[i] instanceof Timestamp timestamp){
                    ps.setTimestamp(i+1,timestamp);
                }
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

    public static <T> Object excute(String sql, Class<T> tClass, Object... args) {
        System.out.println("[log] excuting sql : " + sql);
        System.out.println(Arrays.toString(args));

        PreparedStatement ps = getPreparedStatement(sql, args);
        ResultSet r = null;
        try {
            sql = sql.trim();
            return switch (Character.toLowerCase(sql.charAt(0))) {
                case 'u', 'd', 'i' -> ps.executeUpdate();
                case 's' -> {
                    r = ps.executeQuery();
                    yield new VoAutoBuilder<T>().buildAll(r, tClass);
                }
                default -> null;
            };
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(ps, r);
        }
    }

    public static void close(Connection con, PreparedStatement ps, ResultSet r){
        try {
            if(con != null){
                con.close();
            }
            if(ps != null){
                ps.close();
            }
            if(r != null){
                r.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

    public static void close(PreparedStatement ps,ResultSet r){
        close(conn,ps,r);
    }

}
